﻿# Features:
# string params -begin, -process, -end.  default is -process
# if the last statement in any fragment is missing its ;, then WriteObject(lastStatement);


## as expression
$a = new-list int 4
$a.add(1)
$a.capacity - (cs '$a.count')

if((cs 'Path.HasExtension($a.fullname)')) { 'yup' }

## as cmdlet 

# using LINQ with weakly typed collections
$a = get-process a*
$b = get-process b*
cs '$a.Concat($b)'
# need -WeakType param to turn off generic coercion, or ArrayLists etc that mix types will break

# same, with inline PS syntax
cs '$a.Concat(%% get-process b* %%)'

# pipeline
get-process | cs 'Path.GetDirectoryName($_.path)' | dir
# LINQ shorthand (inferred 'from' clause)
get-process | cs 'where $_.prop1 == $q.tolower() select new {name1 = $_.prop1, name2 = $_.prop2};' | measure -sum name2

# full cmdlet I/O
get-process | cs -begin 'var a = new StringBuilder();' -process 'a.AppendLine($_.tostring());' -end 'a.ToString()'

## as lambda

function map($func, $list) { cs "`$list.Select($func)" }
function reduce($func, $list, $init) { cs "`$list.Aggregate(`$init, $func)" }

$square = 'a => a * a'
map $square 1..3

#TODO: haven't figured out how to compose them.  can't return Func<> types to PS (don't derived from object).
* store in static var?  (make namespace/class determined by PS scope instead of random garbage?)  have to read+clone via reflection every time?
* special -lambda TIn,TOut parameter on either the declaration or the usage?
* does it help if we have -NoCapture option?  For example, "a => a*a" is declared as cs "int a; a*a" -NoCapture

# ideal usage:
$html = 'a => a.Replace("<", "&lt;").Replace(" ","&nbsp;")'
$tabEncode = '(x,y) => String.Format("{0}\t{1}", x, $trans(y)"))'  
reduce $tabEncode 'asdf','j  j','3<4' ''

